<?php
namespace app\app\controller\v1;
use app\app\util\BlockUtils;
use think\Db;
use think\Request;
use app\app\util\OnlineUtils;
use app\app\util\PointUtils;
require_once(dirname(dirname(dirname(__FILE__))).'/util/php/wxBizDataCrypt.php');
use php\WXBizDataCrypt\WXBizDataCrypt;

class AppController extends BaseController{

	/**
	 * [wxlogin description]
	 * @param string code
	 * @return [type] [description]
	 */
    public function login(Request $request){
        //第一次进入应用
        /**
         * 3.小程序调用server获取token接口, 传入code, rawData, signature, encryptData.
         */
        $code = input("post.code");
        $rawData = input("post.rawData");
        $signature = input("post.signature");
        $encryptedData = input("post.encryptedData");
        $iv = input("post.iv");

        /**
         * 4.server调用微信提供的jsoncode2session接口获取openid, session_key, 调用失败应给予客户端反馈
         * , 微信侧返回错误则可判断为恶意请求, 可以不返回. 微信文档链接
         * 这是一个 HTTP 接口，开发者服务器使用登录凭证 code 获取 session_key 和 openid。其中 session_key 是对用户数据进行加密签名的密钥。
         * 为了自身应用安全，session_key 不应该在网络上传输。
         * 接口地址："https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code"
         */
        $params = [
            'appid' => getConfig('APPID'),
            'secret' => getConfig('SECRET'),
            'js_code' => $code,
            'grant_type' => 'authorization_code'
        ];
        $url = "https://api.weixin.qq.com/sns/jscode2session";
        $res = makeRequest($url, $params);
        //result是否存在
        $reqData = json_decode($res);
		//查询用户是否存在
        $user = Db::name('users')->field('id,open_id,nickname,avatar_url,gender')->where('open_id','eq',$reqData->openid)->where('status','eq',1)->find();
		
		if($user){
			$token = md5(time().$user['id']);
            OnlineUtils::sidLogin($token,$user);
            return jsonReturn(200,'success',['token'=>$token,'data'=>$user]);
		}else{
			if (!isset($reqData->session_key)) {
				return jsonReturn('202','未知错误2');
			}
			$sessionKey = $reqData->session_key;

        /**
         * 5.server计算signature, 并与小程序传入的signature比较, 校验signature的合法性, 不匹配则返回signature不匹配的错误. 不匹配的场景可判断为恶意请求, 可以不返回.
         * 通过调用接口（如 wx.getUserInfo）获取敏感数据时，接口会同时返回 rawData、signature，其中 signature = sha1( rawData + session_key )
         *
         * 将 signature、rawData、以及用户登录态发送给开发者服务器，开发者在数据库中找到该用户对应的 session-key
         * ，使用相同的算法计算出签名 signature2 ，比对 signature 与 signature2 即可校验数据的可信度。
         */
        $signature2 = sha1($rawData . $sessionKey);

        if ($signature2 != $signature) return jsonReturn('202','签名错误');


        /**
         *
         * 6.使用第4步返回的session_key解密encryptData, 将解得的信息与rawData中信息进行比较, 需要完全匹配,
         * 解得的信息中也包括openid, 也需要与第4步返回的openid匹配. 解密失败或不匹配应该返回客户相应错误.
         * （使用官方提供的方法即可）
         */
        $pc = new WXBizDataCrypt(getConfig('APPID'), $sessionKey);
        $errCode = $pc->decryptData($encryptedData, $iv, $data );
        if ($errCode !== 0) {
            return jsonReturn('202','验证失败');
        }
        $data = json_decode($data);
        //验证通过
        // $unionid = $data['unionid'];
        $openid = $data->openId;
        //获取登录状态，生成登录码
        $encode_code = base64_encode($openid);
        $access_key  = randomFromDev(100,$encode_code);
        
            // 注册加登录
            $arr = array('open_id'=>$openid,'nickname'=>$data->nickName,'avatar_url'=>$data->avatarUrl,'gender'=>$data->gender);
            //注册时间
            $arr['register_time'] = time();
            $id  = Db::name('users')->insertGetId($arr);
            $arr['id'] = $id;
            //送一张复活卡
            Db::name('user_prop')->insert(array('prop_id'=>1,'user_id'=>$id,'num'=>1));
            //插入签到表
            $sign = array('user_id'=>$id);
            Db::name('sign')->insert($sign);
            //加入闯关信息
            $block = array('user_id'=>$id,'num'=>0,'status'=>1);
            Db::name('block')->insert($block);
            //加入redis闯关排名
            BlockUtils::foundUserBlock($id);
            //加入redis积分排行
            PointUtils::foundUserPoint($id);
            //
            for($i=1;$i<21;$i++){
                Db::name('user_history')->insert(array('user_id'=>$id,'h_id'=>$i,'num'=>0));
            }
            //登录
			$user  = Db::name('users')->where('id','eq',$id)->find();
            $token = md5(time().$id);
            OnlineUtils::login($token,$user);
            return jsonReturn(200,'success',['token'=>$token,'data'=>$arr]);
        }
    }

	/**
	 * [wxCheck 微信验证]
	 * @return [type] [description]
	 */
	public function wxCheck()
	{
    	$signature =  input("get.signature");
        $timestamp =  input("get.timestamp");
    	$nonce     =  input('get.nonce');
    	$token     =  config('WX_TOKEN');
    	$echostr   =  input('get.echostr');
    	$arr       = array($timestamp,$nonce,$token);
    	sort($arr,SORT_STRING);
		$tmpStr    = implode($arr );
		$tmpStr    = sha1( $tmpStr );
		//验证
		if( $signature == $tmpStr ){
			header('content-type:text');
			echo $echostr;
		}else{
			return false;
		}		
	}	
	
	public function test()
	{
//		$user = Db::name('users')->field('id,points')->select();
//		foreach($user as $k => $v){
//			PointUtils::foundUserPoint($v['id'],$v['points']);
//		}
        // Db::query('update a_users set fee = fee - 500');
		// return jsonReturn(200,'success');
		// $key = input('post.key');
		// $num = input('post.num');
		// $id = 0;
		// for($i=1;$i<$num;$i++){
			// BlockUtils::delkey($key,$i);
			// $id++;
		// }
		// $key  = input('post.key');
		// $data = BlockUtils::getKey($key);
		// for($i=0;$i<count($data);$i++){
			// BlockUtils::delkey($data[$i],'');
		// }
		// return jsonReturn(200,'success',$data);
//		$user_id = input('post.id');
//		$token = md5(time().$user_id);
//		$user  = Db::name('users')->where('id','eq',$user_id)->find();
//		OnlineUtils::sidLogin($token,$user);
//        return jsonReturn(200,'success',['token'=>$token,'data'=>$user]);
	}

  
  
}